<?php

namespace App\Http\Services;

use App\Exceptions\ServiceException;
use App\Exceptions\ServiceExceptionConstant;
use App\Http\Repositories\Daos\Team\TeamDao;
use App\Http\Repositories\Daos\Team\TeamUserDao;
use App\Http\Requests\TeamRequest;
use App\Http\Requests\UserContext;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;


class TeamService extends BaseService
{
    protected $teamDao;
    protected $teamUserDao;

    public function __construct(TeamDao $teamDao, TeamUserDao $teamUserDao)
    {
        $this->teamDao     = $teamDao;
        $this->teamUserDao = $teamUserDao;
    }


    public function lists(UserContext $userContext)
    {
        $userId = $userContext->getId();
        $page   = request('page') ?? 1;
        $size   = request('size') ?? 10;
        $offset = ($page * $size) - $size;
        $field  = ['id', 'team_id', 'is_default', 'is_top'];
        $list   = $this->teamUserDao->getModel()
            ->where('user_id', $userId)
            ->whereHas('teamInfo', function (Builder $q) {
                $q->where('status', 1);
            })->limit($size)->offset($offset)->orderBy('is_top', 'desc')->get($field);
        if (!empty($list)) {
            foreach ($list as &$item) {
                $teamInfo           = $item->teamInfo;
                $projectInfo        = $teamInfo->projectInfo;
                $userInfo           = $teamInfo->userInfo;
                $item->team_name    = $teamInfo['name'];
                $item->team_qty     = $teamInfo['qty'];
                $item->discover     = $teamInfo['discover'];
                $item->project_name = $projectInfo['name'];
                $item->captain      = $userInfo['nickname'];
                unset($item->teamInfo);
            }
            unset($item);
        }
        return $list;
    }

    public function userLists()
    {
        $teamId = request('team') ?? 0;
        $page   = request('page') ?? 1;
        $size   = request('size') ?? 10;
        $offset = ($page * $size) - $size;
        $field  = ['id', 'team_id', 'user_id', 'is_captain', 'nickname'];
        return $this->teamUserDao->getModel()->where('team_id', $teamId)->with(["userInfo" => function ($query) {
            $query->select(['id', 'avatar', 'mobile']);
        }])->limit($size)->offset($offset)->orderBy('is_captain', 'desc')->get($field);
    }

    public function createTeam(UserContext $userContext, TeamRequest $teamRequest)
    {
        $userId           = $userContext->getId();
        $data             = $teamRequest->validationData();
        DB::beginTransaction();
        try {
            $data['user_id'] = $userId;
            $model           = $this->teamDao->save($data);
            $teamId          = $model->id;
            $teamUser        = [
                'team_id'    => $teamId,
                'user_id'    => $userId,
                'is_captain' => 1,
                'project_id' => $data['project_id'],
                'nickname'   => $userContext->getNickName()
            ];
            $this->teamUserDao->save($teamUser);
            DB::commit();
        } catch (\Exception $exception) {
            DB::rollBack();
            Log::error('创建队伍失败' . $exception->getMessage());
            throw new ServiceException(ServiceExceptionConstant::getErrorData('创建队伍失败'));
        }
        return true;
    }

    public function entranceTeam(UserContext $userContext)
    {
        $userId = $userContext->getId();
        $teamId = request('team') ?? 0;
        if (empty($teamId) || !is_numeric($teamId)) {
            throw new ServiceException(ServiceExceptionConstant::getErrorData('队伍ID错误'));
        }
        $teamInfo = $this->teamDao->getOne(['id' => $teamId]);
        if (empty($teamInfo)) {
            throw new ServiceException(ServiceExceptionConstant::getErrorData('队伍不存在'));
        }
        if ($teamInfo['status']==0) {
            throw new ServiceException(ServiceExceptionConstant::getErrorData('队伍已解散'));
        }
        $teamUser = $this->teamUserDao->getOne(['team_id' => $teamId, 'user_id' => $userId]);
        if (!empty($teamUser)) {
            throw new ServiceException(ServiceExceptionConstant::getErrorData('你已经在队伍中'));
        }
        DB::beginTransaction();
        try {
            $data = [
                'team_id'    => $teamId,
                'user_id'    => $userId,
                'project_id' => $teamInfo['project_id'],
                'nickname'   => $userContext->getNickName()
            ];

            $this->teamUserDao->save($data);
            $this->teamDao->increment('qty', 1, ['id' => $teamId, 'status' => 1]);
            DB::commit();
        } catch (\Exception $exception) {
            DB::rollBack();
            throw new ServiceException(ServiceExceptionConstant::getErrorData($exception->getMessage()));
        }

        return true;
    }

    public function updateTeam(UserContext $userContext)
    {
        $userId    = $userContext->getId();
        $teamId    = request('team') ?? 0;
        $operation = request('operation') ?? '';
        $val       = request('val') ?? '';
        if (empty($operation) || empty($val)) {
            throw new ServiceException(ServiceExceptionConstant::getErrorData('参数错误'));
        }
        $teamInfo = $this->teamUserDao->getOne(['team_id' => $teamId, 'user_id' => $userId]);
        if (empty($teamInfo)) {
            throw new ServiceException(ServiceExceptionConstant::getErrorData('队伍不存在'));
        }
        if ($teamInfo['user_id'] != $userId && $operation == 3) {
            throw new ServiceException(ServiceExceptionConstant::getErrorData('暂无权限操作'));
        }
        DB::beginTransaction();
        try {
            switch ($operation) {
                //加载队伍
                case 1:
                    $teamInfo->is_default = $val;
                    if ($val == 1) {
                        //更新当前用户所在所有队伍除了当前设置的队伍的加载状态
                        $this->teamUserDao->getModel()->where('team_id', '!=', $teamId)->where('user_id', $userId)->update(['is_default' => 2]);
                    }

                    break;
                //置顶
                case 2:
                    $teamInfo->is_top = $val;
                    $other            = $val == 1 ? 2 : 1;
                    //更新当前用户所在所有队伍除了当前设置的队伍的置顶状态
                    $this->teamUserDao->getModel()->where('team_id', '!=', $teamId)->where('user_id', $userId)->update(['is_top' => $other]);
                    break;
                //解散队伍
                case 3:
                    $this->teamDao->update($teamId, ['status' => 0]);
                    break;
                case 4:
                    $teamInfo->nickname = $val;
                    break;
                default:
                    break;
            }
            $teamInfo->save();
            DB::commit();
            return true;
        } catch (\Exception $exception) {
            DB::rollBack();
            throw new ServiceException(ServiceExceptionConstant::getErrorData('保存失败'));
        }
    }

    public function teamInfo(UserContext $userContext)
    {
        $id        = request('t_id') ?? 0;//队伍id
        $userId    = $userContext->getId();
        $condition = [
            'user_id' => $userId,
            'team_id' => $id
        ];
        $field     = ['id', 'team_id', 'project_id', 'is_captain', 'nickname', 'is_top', 'is_default'];
        $info      = $this->teamUserDao->getOne($condition, $field);
        if (!empty($info)) {
            $teamInfo        = $info->teamInfo;
            $info->team_name = $teamInfo['name'];
            $info->team_qty  = $teamInfo['qty'];
            $info->discover  = $teamInfo['discover'];
            unset($info->teamInfo);
        }
        return $info;
    }

    public function removeMember(UserContext $userContext)
    {
        $userId = $userContext->getId();//操作者：队长的user_id
        $id     = request('id') ?? 0;//要移除的数据id
        $teamId = request('team') ?? 0;
        $info   = $this->teamUserDao->getOne(['team_id' => $teamId, 'id' => $id]);
        if (empty($info)) {
            throw new ServiceException(ServiceExceptionConstant::getErrorData('不在队伍中'));
        }
        $teamInfo = $this->teamDao->getOne(['id' => $teamId]);
        if (empty($teamInfo)) {
            throw new ServiceException(ServiceExceptionConstant::getErrorData('队伍不存在'));
        }
        if ($teamInfo['user_id'] != $userId) {
            throw new ServiceException(ServiceExceptionConstant::getErrorData('您不是队长,不能移除成员'));
        }
        DB::beginTransaction();
        try {
            $this->teamUserDao->deleteByWhere(['id' => $id, 'team_id' => $teamId]);
            $this->teamDao->decrement('qty', 1, ['id' => $teamId]);
            DB::commit();
            return true;
        } catch (\Exception $exception) {
            DB::rollBack();
            throw new ServiceException(ServiceExceptionConstant::getErrorData('移除失败'));
        }
    }

    public function updateUserPos()
    {
        $userId = request('user_id') ?? 0;
        $teamId = request('team') ?? 0;
        $pos    = request('pos') ?? '';
        if (empty($pos)) {
            throw new ServiceException(ServiceExceptionConstant::getErrorData('定位异常'));
        }
        $info = $this->teamUserDao->getOne(['team_id' => $teamId, 'user_id' => $userId]);
        if (empty($info)) {
            throw new ServiceException(ServiceExceptionConstant::getErrorData('队伍异常'));
        }
        $info->pos = $pos;
        $info->save();
        return true;
    }

}
